package com.lx.boot.email;

import com.lx.annotation.Note;
import com.lx.boot.OS;
import com.lx.boot.config.annotation.Properties;
import com.lx.boot.web.valid.Validate;
import com.lx.util.LX;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**  使用方法: OS.getBeanProperty(Mail.class).sendEmail()*/
@Data
@Slf4j
@Properties(prefix = "server.email.smtp")
public class Mail {

    @Note("SMTP服务器域名,默认腾讯邮箱")
    @NotBlank(message = "SMTP服务器域名不能为空!")
    private String host = "smtp.exmail.qq.com";

    @Note("SMTP服务端口,默认465")
    @NotNull(message = "SMTP服务端口不能为空!")
    private Integer port = 465;

    @Note("用户名")
    @NotBlank(message = "用户名不能为空!")
    private String user;

    @Note("密码")
    @NotBlank(message = "密码不能为空!")
    private String password;

    @Note("是否打开调试模式")
    private boolean debug;

    @Data
    public class SendInfo{
        @Note("收件人列表")
        @NotEmpty(message = "收件人列表不能为空!")
        private String[] tos;

        @Note("是否为html")
        private boolean isHtml;

        @Note("抄送人列表")
        private String[] ccs;

        @Note("密送人列表")
        private String[] bccs;

        @Note("回复地址")
        private String[] reply;

        @Note("标题")
        private String subject;

        @Note("正文")
        private String content;
    }
    public static boolean send(String subject, String content, String... tos){
        return OS.getBeanProperty(Mail.class).sendEmail(subject,content,tos);
    }

    @Note("开始发送邮件")
    public boolean sendEmail( String subject, String content, String... tos){
        SendInfo sendInfo = new SendInfo();
        sendInfo.subject = subject;
        sendInfo.content = content;
        sendInfo.tos = tos;
        return sendEmail(sendInfo);
    }
    @Note("开始发送邮件")
    public boolean sendEmail(SendInfo sendInfo){
        if (LX.isEmpty(user) || LX.isEmpty(password)){
            return false;
        }
        Validate.validate(this);
        try{
            log.info("开始发送邮件!");
            java.util.Properties properties = new java.util.Properties();
            properties.put("mail.transport.protocol", "smtp");
            properties.put("mail.smtp.host", host);
            properties.put("mail.smtp.port", port);
            properties.put("mail.smtp.auth", "true");
            properties.put("mail.smtp.ssl.enable", "true");
            properties.put("mail.debug", debug);
            // 得到会话对象
            Session session = Session.getInstance(properties);
            // 获取邮件对象
            Message message = new MimeMessage(session);
            // 设置发件人邮箱地址
            message.setFrom(new InternetAddress(user));
            // 设置邮件标题
            message.setSubject(sendInfo.subject);
            // 设置邮件内容
            message.setContent(sendInfo.content,String.format("text/%s;charset=utf-8",sendInfo.isHtml ? "html" : "plain"));
            // 收件人
            setRecipients(message,Message.RecipientType.TO, sendInfo.tos);
            //抄送人
            setRecipients(message,Message.RecipientType.CC, sendInfo.ccs);
            // 密送人
            setRecipients(message,Message.RecipientType.BCC, sendInfo.bccs);
            //回复地址
            if (LX.isNotEmpty(sendInfo.reply)){
                message.setReplyTo(getAddress(sendInfo.reply));
            }
            Transport tr = session.getTransport("smtp");
            tr.connect(host, user ,password);
            message.saveChanges();
            tr.sendMessage(message,message.getAllRecipients());
            tr.close();
            log.info("邮件发送成功!");
        }catch (Exception e){
            log.error("邮件发送失败!",e);
            return false;
        }
        return true;
    }

    private static void setRecipients(Message message, Message.RecipientType type, String[] address) throws Exception {
        if (LX.isNotEmpty(address)){
            // 抄送人
            message.setRecipients(type,getAddress(address));
        }
    }

    @Note("获取邮箱列表")
    private static InternetAddress[] getAddress(String [] arr) throws AddressException {
        InternetAddress[] ias = new InternetAddress[arr.length];
        for(int i= arr.length-1; i>=0 ; i--){
            ias[i] = new InternetAddress(arr[i]);
        }
        return ias;
    }
}